﻿define('data', ['root', 'system', 'validation'], function (root, system, validation) {
    function initialize() {
        var def = $.Deferred();
        setTimeout(function () {
            $.ajaxSetup({
                cache: false
            });

            def.resolve();
        }, 1);
       
        return def.promise();
    }

    function handleSuccess(data,callback,context) {
        if (data.Success) {
            callback.call(context, null, data.Response);
        } else {
            callback.call(context, data.Error, null);
        }
    }

    function post(resource, dat, callback, context) {
        callback = callback || system.noop;
        $.ajax({
            url: root + resource,
            type: 'POST',
            data: JSON.stringify(dat),
            contentType: "application/json;charset=utf-8",
            dataType: "JSON",
            success: function (data) {
                handleSuccess(data, callback, context);
            },
            error: function () {
                callback.call(context, 'Internal server error', null);
            }
        });
    }

    function get(resource, callback, context) {
        callback = callback || system.noop;
        $.ajax({
            url: root + resource,
            type: 'GET',
            success: function(data) {
                handleSuccess(data, callback, context);
            },
            error: function() {
                callback.call(context, 'Internal server error', null);
            }
        });
    }

    var Crud = function(controller) {
        this.controller = controller;
    };

    Crud.prototype.getAll = function(callback, context) {
        get(this.controller + '/getAll', callback, context);
    };

    Crud.prototype.find = function(id, callback, context) {
        get(this.controller + '/find/' + id, callback, context);
    };

    Crud.prototype.del = function (id, callback, context) {
        post(this.controller + '/delete', { id: id }, callback, context);
    };

    Crud.prototype.save = function(entity, callback, context, action) {
        var method = action || (entity.Id ? 'modify' : 'add');
        var mapping = entity.getMapping ? entity.getMapping : {};
        var data = entity.toJS ? entity.toJS() : ko.mapping.toJS(entity, mapping);
        post(this.controller + '/' + method, data, callback, context);
    };

    var createLookup = function(url, initItem) {
        return {
            minimumInputLength: 0,
            initSelection: function(element, callback) {
                callback(initItem);
            },
            ajax: {
                data: function(term, page) {
                    return {
                        term: term
                    };
                },
                quietMillis: 200,
                cache: true,
                url: url,
                dataType: 'json',
                results: function(data, page) {
                    return {
                        results: data.Response.map(function(item) {
                            return { id: item.Id, text: item.Text };
                        })
                    };
                }
            }
        };
    };

    return {
        initialize: initialize,
        get: get,
        post: post,
        Crud: Crud,
        createLookup: createLookup
    };
});